package com.protocols.sctp.m3ua.sccp.tcap;

import java.io.Serializable;
import java.math.BigInteger;

import com.protocols.BinaryInteger;
import com.protocols.OctaveInteger;
import com.protocols.ProtoOperations;
import com.protocols.ProtocolStackException;
import com.protocols.sctp.m3ua.sccp.SccpUnitDataMsg;

public class TcapPrimitiveUnitNumber extends TcapTag implements Serializable{


	
	private long TagValue=0;
	private Boolean IsSet=false;
	
	public TcapPrimitiveUnitNumber() {
		
	}
	
	public TcapPrimitiveUnitNumber(int tag) {
		super(tag);
	}
	

	public TcapPrimitiveUnitNumber(int tag, long val) {
		super(tag);
		setTagValue(val);
		
	}
	
	
	public byte [] getByteArray(){
		
		if (IsSet)
		{
			byte [] content=getContentBytes();
			
			return ProtoOperations.concatArrays(super.getTagBytes(content.length),content);
		}
		
		return new byte[0];
		
		
		
		
	}

	private byte [] getContentBytes(){
				
		byte [] val = BigInteger.valueOf(TagValue).toByteArray();
		if (val[0]==0 && val.length>1){					// remove the first zero if exist
			byte[] code2 = new byte[val.length-1]; 
			System.arraycopy(val, 1, code2, 0, val.length-1);
			val=code2;
		}
	
		return val;
		
	}
	
	
	public int getLength(){
		return getByteArray().length;
	}

	public int getContentLength(){
		return getContentBytes().length;
	}


	public long getTagValue() {
		
		return TagValue;
	}



	public void setTagValue(long tagValue) {
		TagValue = tagValue;
		IsSet=true;
	}


	
	@Override
	public byte[] decode(byte[] input) {
		
		if (input.length==0)
			return input;
		
		int tagcode= input[0] & 0b00011111;
		int tagclass=(input[0] & 0b11000000)>>6;
		int tagform=(input[0] & 0b00100000)>>5;
		int lengthstart=1;		// Start of the Length
		if (tagcode==31){
			if ((input[1]&0xff)<128){
				tagcode=input[1]&0xff;
				lengthstart=2;
			}
			else{
				
				tagcode=(input[1]<<7) |input[2];
				lengthstart=3;
			}
		}
		
		int taglength=input[lengthstart]& 0xff;
		int noflengthoctets=0;
		if (taglength>128){
			noflengthoctets = input[lengthstart] & 0b01111111;
			taglength= ProtoOperations.intFromByteArray(input, lengthstart+1, noflengthoctets);
		}
		else{
			taglength= input[lengthstart]&0xff;
		}
		byte remainder[]=input; 
		if (this.getTagClass()==tagclass && this.getTagForm()==tagform && this.getTagCode()==tagcode)
		{	
			int tagvaluestart=lengthstart+noflengthoctets+1;			
			
			byte[] tagval=ProtoOperations.extractByteArray(input, tagvaluestart, taglength);
			long val=0;
			for (int i=0; i<tagval.length;i++){
				val=(val<<8|(tagval[i]&0xff));
			}
			setTagValue(val);			
			
			remainder=ProtoOperations.extractByteArray(input, tagvaluestart+taglength, input.length-(tagvaluestart+taglength));
		}
		return remainder;
		
		
	}

	public void setVisible(Boolean visible) {
		
		IsSet=visible;
	}
	
	public Boolean isVisible() {
		
		return IsSet;
	}
	
}
